package com.siyue.test1.Hander;


import com.siyue.test1.entity.Student;
import com.siyue.test1.mapper.StudentMapper;
import com.siyue.test1.service.StudentService;
import com.siyue.test1.util.TransactionalUntil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class SyncStudentHandler {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentService studentService;


    @Async(value = "col")
    public Future<String> syncSaveStudents(List<Student> studentList, int pageIndex) {
        long startTime = System.currentTimeMillis();
        System.out.println("thread name " + Thread.currentThread().getName());
        log.info(String.format("此批数据的段数为:%s 此段数据的数据条数为:%s", pageIndex, studentList.size()));


        //声明future对象
        Future<String> result = new AsyncResult<String>("");

        //循环遍历该段旅客集合
        try {
            //数据入库操作
            studentMapper.saveStudent(studentList);
        } catch (Exception e) {
            //记录出现异常的时间，线程name
            result = new AsyncResult<String>("fail,time=" + System.currentTimeMillis() + ",thread id=" + Thread.currentThread().getName() + ",pageIndex=" + pageIndex);
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime + "," + Thread.currentThread().getName());
        return result;
    }


    @Async(value = "col")
    public Future<List<Student>> syncSelectStudents(int start, int end, int i) {
        System.out.println("start:" + start + ",end:" + end);
        long startTime = System.currentTimeMillis();
        System.out.println("thread name " + Thread.currentThread().getName());
//        log.info(String.format("此批数据的段数为:%s 此段数据的数据条数为:%s", pageIndex, studentList.size()));
        //声明future对象
        List<Student> students = new ArrayList<>();
        try {
            //数据入库操作
            students = studentMapper.studentListByLimit(start, end);
        } catch (Exception e) {
            //记录出现异常的时间，线程name
//            result = new AsyncResult  <List<Student>>("fail,time=" + System.currentTimeMillis() + ",thread id=" + Thread.currentThread().getName() + ",pageIndex=" + i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime + "," + Thread.currentThread().getName());
        return new AsyncResult<List<Student>>(students);
    }

    @Autowired
    private TransactionalUntil transactionalUntil;

    @Async(value = "col")
    public void syncSaveStudents(List<Student> studentList, CountDownLatch childMonitor, CountDownLatch mainMonitor, List<Boolean> childResponse) {
        Long beginTime = System.currentTimeMillis();
        // 开启事务
        TransactionStatus transactionStatus = transactionalUntil.begin();
        try {
            studentMapper.saveStudent(studentList);
            Long endTime = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + "执行完了，花了" + (endTime - beginTime));
            System.out.println(childMonitor.getCount());
            childMonitor.countDown();
            mainMonitor.await(60, TimeUnit.SECONDS);
            if (childResponse.size() == 0) {
                // 事务提交
                log.info("user-线程正常执行,线程事务提交", Thread.currentThread().getName());
                transactionalUntil.commit(transactionStatus);
            } else {
                // 事务回滚
                log.info("user-线程执行出现异常,线程事务回滚", Thread.currentThread().getName());
                transactionalUntil.rollback(transactionStatus);
            }
        } catch (Exception e) {
            // 提交失败
            log.info("user-线程执行出现异常{},", Thread.currentThread().getName());
            childResponse.add(Boolean.FALSE);
            childMonitor.countDown();
            transactionalUntil.rollback(transactionStatus);
        }
    }
}
